package com.hzncc.scaffold.controller.Rear.teachingClassroom.QuestionBank;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.hzncc.scaffold.core.ResultT;
import com.hzncc.scaffold.entity.Bo.QuestionLibListBo;
import com.hzncc.scaffold.entity.Other.*;
import com.hzncc.scaffold.entity.Vo.*;
import com.hzncc.scaffold.mapper.PaperMapper;
import com.hzncc.scaffold.mapper.QuestionlibMapper;
import com.hzncc.scaffold.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: DrunkBear
 * @Date: 2022-05-11 15:29
 * @Description: null
 */
@RestController
@RequestMapping("/manage/paper")
@Api(tags = "教学课堂管理-题库管理-我的测试")
public class MyTestController {

    @Autowired
    PaperMapper paperMapper;

    @Autowired
    PaperService paperService;

    @Autowired
    PapermajorService papermajorService;

    @Autowired
    MajorService majorService;

    @Autowired
    QuestionlibMapper questionlibMapper;

    @Autowired
    QuestionService questionService;

    @Autowired
    QuestionlibService questionlibService;

    @Autowired
    TrainingprogramService trainingprogramService;

    @GetMapping("/list")
    @ApiOperation("我的测试列表")
    public ResultT list(Integer pageNum, Integer pageSize, String keyword, Integer type, Integer majorId) {

        ArrayList<PaperVo> paperVos = new ArrayList<>();

        QueryWrapper<PaperVo> qw = new QueryWrapper<>();
        if (StrUtil.isNotEmpty(keyword) && StrUtil.isNotBlank(keyword)) {
            qw.like("paper.title", keyword);
        }
        if (majorId != null) {
            qw.eq("majors.id", majorId);
        }
        if (type != null) {
            qw.eq("paper.type", type);
        }
        qw.eq("paper.isDelete", 0);
        if (pageNum != null && pageSize != null && pageSize > 0 && pageNum > 0) {
            PageHelper.startPage(pageNum, pageSize * 2);
        }
        List<PaperVo> papers = paperMapper.listPaperPlus(qw);

        for (PaperVo paper : papers) {
            if (CollUtil.isNotEmpty(paperVos)) {
                List<PaperVo> collect = paperVos.stream().filter(item -> item.getId().equals(paper.getId())).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(collect)) {
                    continue;
                }
            }
            Operator operator = new Operator();
            operator.setId(paper.getOperatorId());
            operator.setName(paper.getOperatorName());
            paper.setOperator(operator);

            ArrayList<Major> majors = new ArrayList<>();

            LambdaQueryWrapper<Papermajor> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Papermajor::getPaperId, paper.getId());
            List<Papermajor> papermajorList = papermajorService.list(lqw);

            for (Papermajor papermajor : papermajorList) {
                Major major = majorService.getById(papermajor.getMajorId());
                majors.add(major);
            }

            paper.setMajors(majors);

//            ArrayList<Major> majors = new ArrayList<>();
//
//            ArrayList<Integer> majorIdList = new ArrayList<>();
//            LambdaQueryWrapper<Coursemajor> lqww = new LambdaQueryWrapper<>();
//            lqww.eq(Coursemajor::getCourseId, course.getId());
//            List<Coursemajor> coursemajors = coursemajorService.list(lqww);
//            for (Coursemajor coursemajor : coursemajors) {
//                if (majorService.getById(coursemajor.getMajorId()) != null) {
//                    Major major = majorService.getById(coursemajor.getMajorId());
//                    majorIdList.add(coursemajor.getMajorId());
//                    majors.add(major);
//                }
//            }
//            courseDataListVo.setMajors(majors);



            paperVos.add(paper);
        }
        PageInfo<PaperVo> info = new PageInfo<>();
        info.setList(paperVos);

        Integer total = paperMapper.selectTotal(qw);
        info.setTotal(total);

        HashMap<String,Object> map = new HashMap<>();
        map.put("rows",paperVos);
        map.put("count",total);

        return ResultT.success(map);
    }

    @GetMapping("/detail")
    @ApiOperation("我的测试详情")
    public ResultT detail(Integer paperId) {
        MyTestDetailVo myTestDetailVo = paperService.mytestDetail(paperId);
        return ResultT.success(myTestDetailVo);
    }


    @PostMapping("/update")
    @ApiOperation("修改测试")
    public ResultT update(@RequestBody UpdateMyTestDetailVo updateMyTestDetailVo) {

        List<Integer> questionIdArr = new ArrayList();
        List<QuestionDetailVo> theoryQuestion = new ArrayList();
        List<QuestionDetailVo> operationQuestion =  new ArrayList();
        Integer singleNum = 0;
        Integer multiNum = 0;
        Integer judgeNum = 0;
        Integer operationNum = 0;
        Paper paper = BeanUtil.toBean(updateMyTestDetailVo, Paper.class);
        paper.setId(Integer.valueOf(updateMyTestDetailVo.getPaperId()));
        List<QuestionDetailVo> questionDetailVoList = updateMyTestDetailVo.getQuestion();
        if(CollUtil.isNotEmpty(questionDetailVoList)){
            for (QuestionDetailVo questionDetailVo : questionDetailVoList) {
                questionIdArr.add(questionDetailVo.getId());
                if(questionDetailVo.getType() == 3){
                    operationQuestion.add(questionDetailVo);
                    operationNum++;
                }else {
                    theoryQuestion.add(questionDetailVo);
                    if(questionDetailVo.getType() == 0){
                        singleNum++;
                    }else if(questionDetailVo.getType() == 1){
                        multiNum++;
                    }else if(questionDetailVo.getType() == 2){
                        judgeNum++;
                    }
                }
            }
            paper.setTheoryQuestion(JSONUtil.toJsonStr(theoryQuestion));
            paper.setOperationQuestion(JSONUtil.toJsonStr(operationQuestion));
            paper.setSingleNum(singleNum);
            paper.setMultiNum(multiNum);
            paper.setJudgeNum(judgeNum);
            paper.setOperationNum(operationNum);
        }
        boolean update = paperService.updateById(paper);
        if (update) {
            return ResultT.success("修改成功");
        } else {
            return ResultT.fail("修改失败");
        }
    }

    @PostMapping("/commit")
    @ApiOperation("创建测试")
    public ResultT commit(@RequestBody CommitMyTestDetailVo commitMyTestDetailVo) {
        ResultT resultT = paperService.commit(commitMyTestDetailVo);
//        if (resultT.getCode() == 200) {
//            List<Integer> majorIdList = commitMyTestDetailVo.getMajorId();
//            for (Integer majorId : majorIdList) {
//                Papermajor papermajor = new Papermajor();
//                papermajor.setMajorId(majorId);
//                papermajor.setPaperId((Integer) resultT.getData());
//                papermajorService.save(papermajor);
//            }
//        }
        return resultT;
    }

    @GetMapping("/checkUsed")
    @ApiOperation("校验课程是否被选用")
    public ResultT checkUsed(Integer paperId) {

//        Integer paperId = paperIdVo.getPaperId();

        if (paperId == null) {
            return ResultT.fail("数据错误");
        }
        List<Integer> taskPaperIdList = paperMapper.taskPaperIdList();
        if (CollUtil.contains(taskPaperIdList, paperId)) {
            return ResultT.fail("试卷已被课程选用，不能修改");
        } else {
            Boolean used = false;
            return ResultT.success(used);
        }
    }

    @PostMapping("/delete")
    @ApiOperation("删除测试")
    public ResultT delete(@RequestBody PaperIdVo paperIdVo) {

        Integer paperId = paperIdVo.getPaperId();

        if (paperService.getById(paperId) == null) {
            return ResultT.fail("数据错误");
        }
        Paper paper = paperService.getById(paperId);
        paper.setIsDelete(1);
        boolean update = paperService.updateById(paper);
        if (update) {
            LambdaQueryWrapper<Papermajor> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Papermajor::getPaperId, paperId);
            List<Papermajor> papermajorList = papermajorService.list(lqw);

            if (CollUtil.isNotEmpty(papermajorList)) {
                for (Papermajor papermajor : papermajorList) {
                    if (majorService.getById(papermajor.getMajorId()) != null) {

                        LambdaQueryWrapper<Trainingprogram> lqww = new LambdaQueryWrapper<>();
                        lqww.eq(Trainingprogram::getMajorId,papermajor.getMajorId());
                        trainingprogramService.remove(lqww);

                        majorService.removeById(papermajor.getMajorId());
                    }
                }
            }

            return ResultT.success("删除成功");
        } else {
            return ResultT.fail("删除失败");
        }
    }

    @GetMapping("/questionLibList")
    @ApiOperation("题库数据获取")
    public ResultT questionLibList(Integer majorId, Integer type) {

        QueryWrapper<QuestionLibListBo> qw = new QueryWrapper<>();
        qw.eq("questionlib.isDelete", 0);
        if (majorId != null) {
            qw.eq("majors.id", majorId);
        }
        if (type != null) {

        }
        List<QuestionLibListBo> questionLibListBos = questionlibMapper.questionLibListBo(qw);
        ArrayList<QuestionLibListVo> questionLibListVos = new ArrayList<>();

        for (QuestionLibListBo questionLibListBo : questionLibListBos) {
            QuestionLibListVo questionLibListVo = new QuestionLibListVo();

            questionLibListVo.setId(questionLibListBo.getId());
            questionLibListVo.setTitle(questionLibListBo.getTitle());

            ArrayList<MajorIdAndNameVo> majors = new ArrayList<>();
            MajorIdAndNameVo majorIdAndNameVo = new MajorIdAndNameVo();
            majorIdAndNameVo.setId(questionLibListBo.getMajorsId());
            majorIdAndNameVo.setName(questionLibListBo.getMajorsName());

            majors.add(majorIdAndNameVo);

            questionLibListVo.setMajors(majors);


            LambdaQueryWrapper<Question> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Question::getLibId, questionLibListBo.getId());
            lqw.eq(type != null, Question::getType, type);
            List<Question> questionList = questionService.list(lqw);

            questionLibListVo.setQuestions(questionList);
            questionLibListVos.add(questionLibListVo);

        }

        return ResultT.success(questionLibListVos);
    }

    @GetMapping("/questionList")
    @ApiOperation("题库数据搜索")
    public ResultT questionList(Integer questionLibId, Integer type, String keyword) {
        if (questionlibService.getById(questionLibId) == null) {
            return ResultT.fail("数据错误");
        }
        Questionlib questionlib = questionlibService.getById(questionLibId);
        QuestionListVo questionListVo = new QuestionListVo();
        questionListVo.setId(questionlib.getId());
        questionListVo.setTitle(questionlib.getTitle());

        LambdaQueryWrapper<Question> lqw = new LambdaQueryWrapper<>();
        lqw.eq(questionLibId != null, Question::getLibId, questionLibId);
        lqw.eq(type != null, Question::getType, type);
        lqw.like(StrUtil.isNotEmpty(keyword), Question::getTitle, keyword);
        List<Question> questionList = questionService.list(lqw);

        questionListVo.setQuestions(questionList);

        return ResultT.success(questionListVo);
    }

    @GetMapping("/preview")
    @ApiOperation("预览试卷")
    public ResultT preview(Integer paperId) {

        if (paperService.getById(paperId) == null) {
            return ResultT.fail("数据错误");
        }

        Paper paper = paperService.getById(paperId);

        PreviewVo previewVo = BeanUtil.copyProperties(paper, PreviewVo.class);

        if (StrUtil.isEmpty(paper.getTheoryQuestion())) {
            return ResultT.fail("数据错误");
        }
        JSONArray jsonArray = new JSONArray(paper.getTheoryQuestion());
        List<PreviewQuestionVo> previewQuestionVos = JSONUtil.toList(jsonArray, PreviewQuestionVo.class);

        previewVo.setQuestion(previewQuestionVos);

        return ResultT.success(previewVo);
    }

    @PostMapping("/autoCommit")
    @ApiOperation("智能组卷测试")
    public ResultT autoCommit(@RequestBody AutoCommitVo autoCommitVo) {

        List<Question> allQuestion = new ArrayList<>();
        Integer singleNum = 0;
        Integer multiNum = 0;
        Integer judgeNum = 0;

        Paper paper = BeanUtil.copyProperties(autoCommitVo, Paper.class, "question");

        List<AutoCommitQuestionVo> questions = autoCommitVo.getQuestion();
        for (AutoCommitQuestionVo autoCommitQuestionVo : questions) {
            if (questionlibService.getById(autoCommitQuestionVo.getLibId()) != null) {

                LambdaQueryWrapper<Question> lqw = new LambdaQueryWrapper<>();
                lqw.eq(Question::getLibId, autoCommitQuestionVo.getLibId());

                List<Question> questionList = questionService.list(lqw);

                List<Question> singleQuestionList = questionList.stream().filter(question -> question.getType() == 0).collect(Collectors.toList());
                List<Question> multiQuestionList = questionList.stream().filter(question -> question.getType() == 1).collect(Collectors.toList());
                List<Question> judgeQuestionList = questionList.stream().filter(question -> question.getType() == 2).collect(Collectors.toList());

                List<Question> singleQuestionListNew = RandomUtil.randomEleList(singleQuestionList, autoCommitQuestionVo.getSingleNum());
                List<Question> multiQuestionListNew = RandomUtil.randomEleList(multiQuestionList, autoCommitQuestionVo.getMultiNum());
                List<Question> judgeQuestionListNew = RandomUtil.randomEleList(judgeQuestionList, autoCommitQuestionVo.getJudgeNum());

                allQuestion.addAll(singleQuestionListNew);
                allQuestion.addAll(multiQuestionListNew);
                allQuestion.addAll(judgeQuestionListNew);

                singleNum = singleNum + autoCommitQuestionVo.getSingleNum();
                multiNum = multiNum + autoCommitQuestionVo.getMultiNum();
                judgeNum = judgeNum + autoCommitQuestionVo.getJudgeNum();
            }
        }

        String allQuestionStr = JSONUtil.toJsonStr(allQuestion);
        paper.setTheoryQuestion(allQuestionStr);
        paper.setSingleNum(singleNum);
        paper.setMultiNum(multiNum);
        paper.setJudgeNum(judgeNum);
        paper.setOperatorId(StpUtil.getLoginIdAsInt());
        paper.setCreateTime(DateUtil.now());

        boolean save = paperService.save(paper);
        if (save) {
            List<Integer> majorIdList = autoCommitVo.getMajorId();
            for (Integer majorId : majorIdList) {
                Papermajor papermajor = new Papermajor();
                papermajor.setMajorId(majorId);
                papermajor.setPaperId(paper.getId());

                papermajorService.save(papermajor);

            }

            return ResultT.success("操作成功");
        } else {
            return ResultT.fail("操作失败");
        }
    }

    @GetMapping("/export")
    @ApiOperation("导出试卷")
    public void export(Integer paperId, HttpServletResponse response) throws IOException {

        Paper paper = paperService.getById(paperId);

        MyTestDetailVo myTestDetailVo = paperService.mytestDetail(paperId);
        ArrayList<Map<String, Object>> exportCourseDataVos = new ArrayList<>();

        List<QuestionDetailVo> questionList = myTestDetailVo.getQuestion();
        for (QuestionDetailVo question : questionList) {
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();

            if (question.getType() == 0) {
                map.put("题型", "单选题");
            }

            if (question.getType() == 1) {
                map.put("题型", "多选题");
            }

            if (question.getType() == 2) {
                map.put("题型", "判断题");
            }

            map.put("题干内容",question.getTitle());
            map.put("正确答案",question.getAnswer());
            map.put("答案解析",question.getAnalyse());

            List<String> optionSplit = StrUtil.split(question.getOption(), "&&");

            ArrayList<String> modelList = new ArrayList<>();
            modelList.add("选项A");
            modelList.add("选项B");
            modelList.add("选项C");
            modelList.add("选项D");
            modelList.add("选项E");
            modelList.add("选项F");

            for (int i = 0; i < optionSplit.size(); i++) {
                map.put(modelList.get(i), optionSplit.get(i));
            }

            exportCourseDataVos.add(map);
        }
        if (CollUtil.isNotEmpty(exportCourseDataVos)) {

            ExcelWriter writer = ExcelUtil.getWriter();
            writer.write(exportCourseDataVos, true);
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            String fileName = URLEncoder.encode(paper.getTitle() + ".xls", "UTF-8");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            ServletOutputStream out = response.getOutputStream();
            writer.flush(out);
            writer.close();
        }
    }
}
